#include "ring_buffer.h"
#include <string.h>

void RingBuff_Init(RingBuffer_Def *rb, RingBuff_FullPolicy policy)
{
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
    rb->policy = policy;
    memset(rb->buffer, 0, sizeof(rb->buffer));
}

void RingBuff_Clear(RingBuffer_Def *rb)
{
    rb->head = rb->tail = rb->count = 0;
}

uint8_t RingBuff_Count(RingBuffer_Def *rb)
{
    return rb->count;
}

// ================= push_back =================
bool RingBuff_PushBack(RingBuffer_Def *rb, uint32_t val)
{
    if (rb->count >= RingBuff_MAX_SIZE)
    {
        if (rb->policy == RingBuff_DISCARD_NEW)
            return false; // 队列满，丢弃新数据
        else              // RingBuff_OVERWRITE_OLD
        {
            rb->tail = (rb->tail + 1) % RingBuff_MAX_SIZE; // 覆盖最旧数据
            rb->count--;
        }
    }

    rb->buffer[rb->head] = val;
    rb->head = (rb->head + 1) % RingBuff_MAX_SIZE;
    rb->count++;
    return true;
}

// ================= push_front =================
bool RingBuff_PushFront(RingBuffer_Def *rb, uint32_t val)
{
    if (rb->count >= RingBuff_MAX_SIZE)
    {
        if (rb->policy == RingBuff_DISCARD_NEW)
            return false;
        else // 覆盖尾部数据
        {
            rb->head = (rb->head == 0 ? RingBuff_MAX_SIZE - 1 : rb->head - 1);
            rb->count--;
        }
    }

    rb->tail = (rb->tail == 0 ? RingBuff_MAX_SIZE - 1 : rb->tail - 1);
    rb->buffer[rb->tail] = val;
    rb->count++;
    return true;
}

// ================= pop_front =================
bool RingBuff_PopFront(RingBuffer_Def *rb, uint32_t *val)
{
    if (rb->count == 0)
        return false;

    *val = rb->buffer[rb->tail];
    rb->tail = (rb->tail + 1) % RingBuff_MAX_SIZE;
    rb->count--;
    return true;
}

// ================= pop_back =================
bool RingBuff_PopBack(RingBuffer_Def *rb, uint32_t *val)
{
    if (rb->count == 0)
        return false;

    rb->head = (rb->head == 0 ? RingBuff_MAX_SIZE - 1 : rb->head - 1);
    *val = rb->buffer[rb->head];
    rb->count--;
    return true;
}
